package us.icitap.cm.business.entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.eclipse.persistence.annotations.Customizer;

import us.icitap.cm.utils.MyCustomizer;
import us.icitap.utils.FormatingUtils;

@Entity
@Customizer(MyCustomizer.class)
@Table(name="CONTROL",schema="MPC")
//@TableGenerator(name="CONTROL_IDS",table="AUTO_IDS",valueColumnName="LAST_ID",initialValue=1, allocationSize=1,schema="MPC")
public class Control implements Serializable{

	
	/**
	 * 
	 */
	private static final long serialVersionUID = -4742850553047450291L;

	public enum ControlTypeEnum{
		PLACE("Vendi/Objekti"),
		PERSON("Personi"),
		VEHICLE("Automjeti");
		
		private String caption;
		private ControlTypeEnum(String caption){
			this.caption = caption;
		}
		
		public String getCaption(){
			return this.caption;
		}
	}
	
	public enum ControlRequestEnum{
		ACCEPTED("Pranuar"),
		REFUSED("Refuzuar");
		
		private String caption;
		private ControlRequestEnum(String caption){
			this.caption = caption;
		}
		
		public String getCaption(){
			return this.caption;
		}
	}
	
	@Id
	@Column(insertable=false, updatable = false)
	private Integer id;
	
	
	@OneToOne
	@JoinColumn(name="ID",nullable=false)
	private AppEntity appEntity;
	
	
	@ManyToOne
	@JoinColumn(name="SUBJECT_APP_ENTITY_ID")
	private AppEntity subjectAppEntity;
	
	
	@Enumerated(EnumType.STRING)
	@Column(name="CONTROL_TYPE")
	private ControlTypeEnum controlType;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="START_DATE")
	private Date startDate;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="END_DATE")
	private Date endDate;
	
	@Column(name="COURT_DECISION")
	private boolean courtDecision;
	
	@Column(name="COURT_DECISION_NO", length=8)
	private String courtDecisionNo;
	
	@Temporal(TemporalType.DATE)
	@Column(name="COURT_DECISION_DATE")
	private Date courtDecisionDate;
	
	@Column(name="OFFICER_INICIATIVE")
	private boolean officerIniciative;
	
	@ManyToOne
	@JoinColumn(name="CONTROL_REASON_ID")
	private AppList controlReason;
	
	@Enumerated(EnumType.STRING)
	@Column(name="CONTROL_REQUEST")
	private ControlRequestEnum controlRequestEnum;
	
	@OneToMany(cascade=CascadeType.ALL,mappedBy="control")
	private List<ControlAppEntityFound> controlAppEntityFoundList;
	
	@ManyToOne
	@JoinColumn(name="REPORT_ID")
	private Report report;

	
	public Control(Control control){
		this.subjectAppEntity = control.getSubjectAppEntity();
		this.controlReason = control.getControlReason();
		this.controlRequestEnum = control.getControlRequestEnum();
		this.controlType = control.getControlType();
		this.courtDecision = control.isCourtDecision();
		this.courtDecisionDate = control.getCourtDecisionDate();
		this.courtDecisionNo = control.getCourtDecisionNo();
		this.endDate = control.getEndDate();
		this.startDate = control.getStartDate();
		this.officerIniciative = control.isOfficerIniciative();
		this.report = control.getReport();
		
		this.addControlAppEntityFoundList(control.getControlAppEntityFoundList());
		
	}
	
	public Control(){
		
	}
	
	@Transient
	public List<AppEntity> getPersonEntityFoundList(){
		
		if( this.getControlAppEntityFoundList() == null ||  this.getControlAppEntityFoundList().isEmpty()) return null;
		List<AppEntity> list = new ArrayList<AppEntity>();
		
		for (ControlAppEntityFound caef : this.getControlAppEntityFoundList()) {
			if (caef.getAppEntity().getEntityType().equals(EntityTypeEnum.PERSON))
				list.add(caef.getAppEntity());
		}
		
		return list;
	}
	
	@Transient
	public List<ControlAppEntityFound> getNonPersonEntityFoundList(){
		
		if( this.getControlAppEntityFoundList() == null ||  this.getControlAppEntityFoundList().isEmpty()) return null;
		List<ControlAppEntityFound> list = new ArrayList<ControlAppEntityFound>();
		
		for (ControlAppEntityFound caef : this.getControlAppEntityFoundList()) {
			if (!caef.getAppEntity().getEntityType().equals(EntityTypeEnum.PERSON))
				list.add(caef);
		}
		
		return list;
	}
	
	
	public void addControlAppEntityFound(ControlAppEntityFound controlAppEntityFound){
		if(controlAppEntityFoundList == null) this.controlAppEntityFoundList = new ArrayList<ControlAppEntityFound>();
		this.controlAppEntityFoundList.add(controlAppEntityFound);
	}
	
	public void removeControlAppEntityFound(ControlAppEntityFound controlAppEntityFound){
		if(controlAppEntityFoundList == null) return;
		this.controlAppEntityFoundList.remove(controlAppEntityFound);
	}
	
	public void addControlAppEntityFoundList(List<ControlAppEntityFound> controlAppEntityFoundList){
		if(this.controlAppEntityFoundList == null && controlAppEntityFoundList != null) this.controlAppEntityFoundList = new ArrayList<ControlAppEntityFound>();
		this.controlAppEntityFoundList.addAll(controlAppEntityFoundList);
	}
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public ControlTypeEnum getControlType() {
		return controlType;
	}

	public void setControlType(ControlTypeEnum controlType) {
		this.controlType = controlType;
	}

	public boolean isCourtDecision() {
		return courtDecision;
	}

	public void setCourtDecision(boolean courtDecision) {
		this.courtDecision = courtDecision;
	}

	public String getCourtDecisionNo() {
		return courtDecisionNo;
	}

	public void setCourtDecisionNo(String courtDecisionNo) {
		this.courtDecisionNo = courtDecisionNo;
	}

	public Date getCourtDecisionDate() {
		return courtDecisionDate;
	}

	public void setCourtDecisionDate(Date courtDecisionDate) {
		this.courtDecisionDate = courtDecisionDate;
	}

	public boolean isOfficerIniciative() {
		return officerIniciative;
	}

	public void setOfficerIniciative(boolean officerIniciative) {
		this.officerIniciative = officerIniciative;
	}

	public AppList getControlReason() {
		return controlReason;
	}

	public void setControlReason(AppList controlReason) {
		this.controlReason = controlReason;
	}

	public ControlRequestEnum getControlRequestEnum() {
		return controlRequestEnum;
	}

	public void setControlRequestEnum(ControlRequestEnum controlRequestEnum) {
		this.controlRequestEnum = controlRequestEnum;
	}

	public Report getReport() {
		return report;
	}

	public void setReport(Report report) {
		this.report = report;
	}

	public AppEntity getAppEntity() {
		return appEntity;
	}

	public void setAppEntity(AppEntity appEntity) {
		this.appEntity = appEntity;
	}

	@Override
	public String toString() {
		return "Kontroll dt:" + FormatingUtils.formatedDate(this.startDate);
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public AppEntity getSubjectAppEntity() {
		return subjectAppEntity;
	}

	public void setSubjectAppEntity(AppEntity subjectAppEntity) {
		this.subjectAppEntity = subjectAppEntity;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		
		result = prime
				* result
				+ ((controlAppEntityFoundList == null) ? 0 : controlAppEntityFoundList
						.hashCode());
		result = prime * result
				+ ((controlReason == null) ? 0 : controlReason.hashCode());
		result = prime
				* result
				+ ((controlRequestEnum == null) ? 0 : controlRequestEnum
						.hashCode());
		result = prime * result
				+ ((controlType == null) ? 0 : controlType.hashCode());
		result = prime * result + (courtDecision ? 1231 : 1237);
		result = prime
				* result
				+ ((courtDecisionDate == null) ? 0 : courtDecisionDate
						.hashCode());
		result = prime * result
				+ ((courtDecisionNo == null) ? 0 : courtDecisionNo.hashCode());
		result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + (officerIniciative ? 1231 : 1237);
		result = prime * result + ((report == null) ? 0 : report.hashCode());
		result = prime * result
				+ ((startDate == null) ? 0 : startDate.hashCode());
		result = prime
				* result
				+ ((subjectAppEntity == null) ? 0 : subjectAppEntity.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Control other = (Control) obj;
		if (appEntity == null) {
			if (other.appEntity != null)
				return false;
		} else if (!appEntity.equals(other.appEntity))
			return false;
		if (controlAppEntityFoundList == null) {
			if (other.controlAppEntityFoundList != null)
				return false;
		} else if (!controlAppEntityFoundList.equals(other.controlAppEntityFoundList))
			return false;
		if (controlReason == null) {
			if (other.controlReason != null)
				return false;
		} else if (!controlReason.equals(other.controlReason))
			return false;
		if (controlRequestEnum != other.controlRequestEnum)
			return false;
		if (controlType != other.controlType)
			return false;
		if (courtDecision != other.courtDecision)
			return false;
		if (courtDecisionDate == null) {
			if (other.courtDecisionDate != null)
				return false;
		} else if (!courtDecisionDate.equals(other.courtDecisionDate))
			return false;
		if (courtDecisionNo == null) {
			if (other.courtDecisionNo != null)
				return false;
		} else if (!courtDecisionNo.equals(other.courtDecisionNo))
			return false;
		if (endDate == null) {
			if (other.endDate != null)
				return false;
		} else if (!endDate.equals(other.endDate))
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (officerIniciative != other.officerIniciative)
			return false;
		if (report == null) {
			if (other.report != null)
				return false;
		} else if (!report.equals(other.report))
			return false;
		if (startDate == null) {
			if (other.startDate != null)
				return false;
		} else if (!startDate.equals(other.startDate))
			return false;
		if (subjectAppEntity == null) {
			if (other.subjectAppEntity != null)
				return false;
		} else if (!subjectAppEntity.equals(other.subjectAppEntity))
			return false;
		return true;
	}


	public boolean myEquals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Control other = (Control) obj;
		
		if (controlAppEntityFoundList == null) {
			if (other.controlAppEntityFoundList != null)
				return false;
		} else if (!controlAppEntityFoundList.equals(other.controlAppEntityFoundList))
			return false;
		if (controlReason == null) {
			if (other.controlReason != null)
				return false;
		} else if (!controlReason.equals(other.controlReason))
			return false;
		if (controlRequestEnum != other.controlRequestEnum)
			return false;
		if (controlType != other.controlType)
			return false;
		if (courtDecision != other.courtDecision)
			return false;
		if (courtDecisionDate == null) {
			if (other.courtDecisionDate != null)
				return false;
		} else if (!courtDecisionDate.equals(other.courtDecisionDate))
			return false;
		if (courtDecisionNo == null) {
			if (other.courtDecisionNo != null)
				return false;
		} else if (!courtDecisionNo.equals(other.courtDecisionNo))
			return false;
		if (endDate == null) {
			if (other.endDate != null)
				return false;
		} else if (!endDate.equals(other.endDate))
			return false;
		if (officerIniciative != other.officerIniciative)
			return false;
		if (report == null) {
			if (other.report != null)
				return false;
		} else if (!report.equals(other.report))
			return false;
		if (startDate == null) {
			if (other.startDate != null)
				return false;
		} else if (!startDate.equals(other.startDate))
			return false;
		if (subjectAppEntity == null) {
			if (other.subjectAppEntity != null)
				return false;
		} else if (!subjectAppEntity.equals(other.subjectAppEntity))
			return false;
		return true;
	}

	public List<ControlAppEntityFound> getControlAppEntityFoundList() {
		return controlAppEntityFoundList;
	}

	public void setControlAppEntityFoundList(
			List<ControlAppEntityFound> controlAppEntityFoundList) {
		this.controlAppEntityFoundList = controlAppEntityFoundList;
	}
	
}
